package cn.com.zcode.core.cxf.client;

import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;

@SuppressWarnings("rawtypes")
public class MapConvert implements Convert {
	Logger logger = Logger.getLogger(MapConvert.class);

	@SuppressWarnings("unchecked")
	@Override
	public Object format(Object obj, Type type) {
		boolean canFormat = Map.class.equals(type) || (type instanceof ParameterizedType && Map.class.equals(((ParameterizedType) type).getRawType()));
		if (canFormat) {
			Class<?> zlass = obj.getClass();
			Type key = null;
			Type value = null;
			if (type instanceof ParameterizedType) {
				ParameterizedType parameterizedType = (ParameterizedType) type;
				Type[] types = parameterizedType.getActualTypeArguments();
				key = types[0];
				value = types[1];
				logger.info("Generics type info:" + parameterizedType);
			}
			HashMap<Object, Object> map = new LinkedHashMap<Object, Object>();
			try {
				Method method = zlass.getMethod("getEntry");
				List<?> list = (List<?>) method.invoke(obj);
				for (Object object : list) {
					Class<?> olass = object.getClass();
					Method km = olass.getMethod("getKey");
					Method vm = olass.getMethod("getValue");
					Object okey = km.invoke(object);
					Object oval = vm.invoke(object);
					if (key != null && !okey.getClass().equals(key)) {
						okey = ConvertUtil.convert(okey, (Class) key);
					}
					if (value != null && !oval.getClass().equals(value)) {
						oval = ConvertUtil.convert(oval, (Class) value);
					}
					map.put(okey, oval);
				}

			} catch (Exception e) {
				e.printStackTrace();
			}
			logger.debug("Convert format Info: " + obj + " -> " + HashMap.class);
			return map;
		}
		return obj;
	}

	@Override
	public Object parse(Object obj) {
		return obj;
	}

}